home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / apps.to.go / DTS.StyleChat / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-18  |  13.5 KB  |  529 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        Menu.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1990-1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19.  
  20.  
  21. /*****************************************************************************/
  22.  
  23.  
  24.  
  25. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  26. #include "App.defs.h"        /* Get various application definitions.            */
  27. #include "App.protos.h"        /* Get the prototypes for application.            */
  28.  
  29. #ifndef __DESK__
  30. #include <Desk.h>
  31. #endif
  32.  
  33. #ifndef __ERRORS__
  34. #include <Errors.h>
  35. #endif
  36.  
  37. #ifndef __FONTS__
  38. #include <Fonts.h>
  39. #endif
  40.  
  41. #ifndef __MEMORY__
  42. #include <Memory.h>
  43. #endif
  44.  
  45. #ifndef __MENUS__
  46. #include <Menus.h>
  47. #endif
  48.  
  49. #ifndef __TOOLUTILS__
  50. #include <ToolUtils.h>
  51. #endif
  52.  
  53. #ifndef __UTILITIES__
  54. #include "Utilities.h"
  55. #endif
  56.  
  57.  
  58.  
  59. /*****************************************************************************/
  60.  
  61.  
  62.  
  63. extern Boolean    gQuitApplication;
  64. extern Boolean    gHasAppleEvents;
  65. extern OSType    gAppWindowType;
  66.  
  67. extern Boolean    gLowOnMem;
  68. extern short    gDialogErr;
  69.  
  70. static short    NewFontSize(short size);
  71.  
  72.  
  73.  
  74. /*****************************************************************************/
  75. /*****************************************************************************/
  76.  
  77.  
  78.  
  79. /* •• Called by DTS.Lib..framework. •• */
  80.  
  81. /* Adjust the menu items.  We allow the DTS.Lib framework to do most of the work
  82. ** for us.  It will walk the menubar, and for each menu in the menubar, it will
  83. ** disable all of the menu items and then call the application at either
  84. ** AdjustMenuItems() (for document and palette windows, or for the no-window case),
  85. ** or DialogAdjustMenuItems() (for modal dialogs).  The application's job is to then
  86. ** turn on menu items that should be enabled to match the current application state.
  87. ** The initial Wannabe code for AdjustMenuItems() calls DoAdjustFileMenu() for the
  88. ** file menu, and DoAdjustEditMenu() for the edit menu.  Any other menus that may
  89. ** be added to Wannabe have all menu items enabled.  This allows menus to be added
  90. ** to the running version of Wannabe and allows them to actually do something.
  91. ** If the top-most window is a dialog, then all menus are disabled except for the
  92. ** edit menu.  Various items in the edit menu are enabled, depending on if there
  93. ** is an active TextEdit control, and what is in the clipboard. */
  94.  
  95. #pragma segment Menu
  96. void    DoAdjustMenus(void)
  97. {
  98.     if (DoAdjustMBARMenus(FrontWindow(), rMenuBar))
  99.         DrawMenuBar();
  100. }
  101.  
  102.  
  103.  
  104. /*****************************************************************************/
  105.  
  106.  
  107.  
  108. /* This is called when an item is chosen from the menu bar (after calling
  109. ** MenuSelect or MenuKey).  It performs the right operation for each command.
  110. ** It is good to have both the result of MenuSelect and MenuKey go to one
  111. ** routine like this to keep everything organized. */
  112.  
  113. #pragma segment Menu
  114. Boolean    DoMenuCommand(short menuID, short menuItem)
  115. {
  116.     short            undoDepth, numUndos, saveMode, daRefNum, mode, size;
  117.     Str255            str;
  118.     FileRecHndl        frHndl, newFrHndl;
  119.     WindowPtr        window;
  120.     TEHandle        te;
  121.     OSErr            err;
  122.     Boolean            handled;
  123.     TEHandle        teHndl;
  124.     TextStyle        styl;
  125.     MenuHandle        menu;
  126.     static Style    stylVal[] = {0, 0, 0, 1, 2, 4, 8, 16, 32, 64};
  127.  
  128.     handled = true;
  129.  
  130.     window = FrontWindow();
  131.     if (window)
  132.         frHndl = (FileRecHndl)GetWRefCon(window);
  133.             /* frHndl is valid only if it is one of our windows. */
  134.  
  135.     switch (menuID) {
  136.  
  137.         case mApple:
  138.             switch (menuItem) {
  139.                 case kStdAbout:        /* Bring up alert for About. */
  140.                     NewDocumentWindow(nil, 'ABOT', false);
  141.                     break;
  142.                 default:            /* All non-About items in this menu are DAs. */
  143.                     GetMenuItemText(GetMenuHandle(mApple), menuItem, str);
  144.                     daRefNum = OpenDeskAcc(str);
  145.                     break;
  146.             }
  147.             break;
  148.  
  149.         case mFile:
  150.             switch (menuItem) {
  151.                 case kStdNew:
  152.                     gDialogErr = NewDocumentWindow(&frHndl, gAppWindowType, true);
  153.                     if (gDialogErr)
  154.                         NewDocumentWindow(nil, 'ERR#', false);
  155.                     break;
  156.                 case kStdOpen:
  157.                     err = OpenDocumentWindow(&frHndl, nil, fsRdWrPerm);
  158.                     if ((err) && (err != userCanceledErr)) {
  159.                         gDialogErr = err;
  160.                         NewDocumentWindow(nil, 'ERR#', false);
  161.                     }
  162.                     break;
  163.                 case kStdClose:
  164.                     if (IsAppWindow(window)) {
  165.                         window = FrontWindowOfType(kwIsDocument, true);
  166.                         if (window)
  167.                             DisposeOneWindow(window, kClose);
  168.                     }
  169.                     else
  170.                         DisposeOneWindow(window, kClose);        /* Dispose of DA window. */
  171.                     break;
  172.                 case kStdSave:
  173.                 case kStdSaveAs:
  174.                     saveMode = (menuItem == kStdSave) ? kSave : kSaveAs;
  175.                     if ((*frHndl)->fileState.refNum == kInvalRefNum)
  176.                         saveMode = kSaveAs;
  177.                     err = SaveDocument(frHndl, window, saveMode);
  178.                     if ((err) && (err != userCanceledErr)) {
  179.                         gDialogErr = err;
  180.                         NewDocumentWindow(nil, 'ERR#', false);
  181.                     }
  182.                     break;
  183.                 case kDuplicate:
  184.                     gDialogErr = DuplicateDocument(frHndl, &newFrHndl);
  185.                     if (!gDialogErr) {
  186.                         gDialogErr = DoNewWindow(newFrHndl, nil, FrontWindowOfType(kwIsDocument, true), (WindowPtr)-1);
  187.                         if (gDialogErr)
  188.                             DisposeDocument(newFrHndl);
  189.                     }
  190.                     if (gDialogErr)
  191.                         NewDocumentWindow(nil, 'ERR#', false);
  192.                     break;
  193.                 case kStdPageSetup:
  194.                     DoSetCursor(&qd.arrow);
  195.                     PresentStyleDialog(frHndl);
  196.                     break;
  197.                 case kStdPrint:
  198.                     DoSetCursor(&qd.arrow);
  199.                     err = noErr;
  200.                     if (!(*frHndl)->d.doc.fhInfo.printRecValid)
  201.                         err = PresentStyleDialog(frHndl);
  202.                     if (!err) {
  203.                         err = PrintDocument(frHndl, true, true);
  204.                         PrintDocument(nil, false, false);
  205.                     }
  206.                     if ((err) && (err != userCanceledErr)) {
  207.                         gDialogErr = err;
  208.                         NewDocumentWindow(nil, 'ERR#', false);
  209.                     }
  210.                     break;
  211.                 case kStdQuit:
  212.                     gQuitApplication = DisposeAllWindows();
  213.                     break;
  214.                 default:
  215.                     handled = false;
  216.                     break;
  217.             }
  218.             break;
  219.  
  220.         case mEdit:            /* Call SystemEdit for DA editing & MultiFinder. */
  221. #if VH_VERSION
  222.             if (menuItem == kStdViewHier) {
  223.                 handled = false;
  224.                 break;
  225.             }
  226. #endif
  227.             if (IsAppWindow(window)) {
  228.                 switch (menuItem) {
  229.                     case kStdUndo:
  230.                     case kStdRedo:
  231.                     case kStdCut:
  232.                     case kStdCopy:
  233.                     case kStdPaste:
  234.                     case kStdClear:
  235.                         switch ((*frHndl)->fileState.sfType) {
  236.                                 /* This is written with the assumption that document types
  237.                                 ** that demand specific code will be added.  The below “if”
  238.                                 ** illustrates how to handle the edit menu for windows that
  239.                                 ** have an active TextEdit control.  The “else” shows a typical
  240.                                 ** undo/redo scenario for applications that are using the
  241.                                 ** hierarchical document package.  The clipboard features
  242.                                 ** are of course document-dependent, so a sample hasn't been
  243.                                 ** implemented here.  For a sample, see DTS.Draw. */
  244.                             default:
  245.                                 te = CTEFindActive(window);
  246.                                 if (te) {
  247.                                     if ((*te)->viewRect.left < -8192)
  248.                                         BeginFrame(window);
  249.                                     else
  250.                                         BeginContent(window);
  251.                                     if (menuItem == kStdUndo)
  252.                                         CTEUndo();
  253.                                     else
  254.                                         CTEClipboard(menuItem - kStdCut + 2);
  255.                                     EndContent(window);
  256.                                 }
  257.                                 else {
  258.                                     if (menuItem <= kStdRedo) {
  259.                                         if (!UnmapMItem(mEdit, kStdUndo)) {
  260.                                             GetUndoInfo(frHndl, &undoDepth, &numUndos);
  261.                                             DoUndoTask((*frHndl)->d.doc.root, 1 - undoDepth, true);
  262.                                         }
  263.                                         else DoUndoTask((*frHndl)->d.doc.root, menuItem - kStdUndo, true);
  264.                                     }
  265.                                     else {
  266.                                         /* Handle rest of edit menu here. */
  267.                                     }
  268.                                 }
  269.                                 break;
  270.                         }
  271.                         break;
  272.                 }
  273.             }
  274.             else SystemEdit(menuItem - 1);
  275.             break;
  276.  
  277.         case mFonts:
  278.             teHndl = CTEFindActive(nil);
  279.             if (teHndl) {
  280.                 if (menuItem <= kExtend) {
  281.                     if ((*teHndl)->selStart != (*teHndl)->selEnd)
  282.                         CTENewUndo(CTEViewFromTE(teHndl), true);
  283.                     mode = (styl.tsFace = stylVal[menuItem]) ? (doFace | doToggle) : (doFace);
  284.                     TESetStyle(mode, &styl, true, teHndl);
  285.                     CTEAdjustTEBottom(teHndl);
  286.                     CTEAdjustScrollValues(teHndl);
  287.                     SetDocDirty(frHndl);
  288.                 }
  289.                 if (menuItem == kFontSize) {
  290.                     if ((*teHndl)->selStart != (*teHndl)->selEnd)
  291.                         CTENewUndo(CTEViewFromTE(teHndl), true);
  292.                     size = 0;
  293.                     mode = doSize;
  294.                     TEContinuousStyle(&mode, &styl, teHndl);
  295.                     if (mode)
  296.                         if (!(size = styl.tsSize))
  297.                             size = 12;
  298.                     styl.tsSize = NewFontSize(size);
  299.                     if (styl.tsSize) {
  300.                         TESetStyle(doSize, &styl, true, teHndl);
  301.                         CTEAdjustTEBottom(teHndl);
  302.                         CTEAdjustScrollValues(teHndl);
  303.                         SetDocDirty(frHndl);
  304.                     }
  305.                 }
  306.                 if (menuItem >= kFirstFont) {
  307.                     if ((*teHndl)->selStart != (*teHndl)->selEnd)
  308.                         CTENewUndo(CTEViewFromTE(teHndl), true);
  309.                     menu = GetMenuHandle(mFonts);
  310.                     GetMenuItemText(menu, menuItem, str);
  311.                     GetFNum(str, &styl.tsFont);
  312.                     TESetStyle(doFont, &styl, true, teHndl);
  313.                     CTEAdjustTEBottom(teHndl);
  314.                     CTEAdjustScrollValues(teHndl);
  315.                     SetDocDirty(frHndl);
  316.                 }
  317.             }
  318.             break;
  319.  
  320.         default:
  321.             handled = false;
  322.             break;
  323.  
  324.     }
  325.  
  326.     return(handled);
  327. }
  328.  
  329.  
  330.  
  331. /*****************************************************************************/
  332.  
  333.  
  334.  
  335. #pragma segment Menu
  336. Boolean    DoAdjustFileMenu(WindowPtr window)
  337. {
  338.     MenuHandle    menu;
  339.     FileRecHndl    frHndl;
  340.     short        enableItem;
  341.  
  342.     menu = GetMenuHandle(mFile);
  343.     EnableItem(menu, UnmapMItem(mFile, kStdQuit));            /* Gotta be able to quit. */
  344.  
  345.     if (IsDAWindow(window)) {
  346.         EnableItem(menu, UnmapMItem(mFile, kStdClose));        /* Let DAs do a close from the menu. */
  347.         return(false);
  348.     }
  349.  
  350.     if (!gLowOnMem) {
  351.         EnableItem(menu, UnmapMItem(mFile, kStdNew));
  352.         EnableItem(menu, UnmapMItem(mFile, kStdOpen));
  353.     }
  354.  
  355.     window = FrontWindowOfType(kwIsDocument, true);
  356.     if (window) {
  357.         EnableItem(menu, UnmapMItem(mFile, kStdClose));
  358.         frHndl = (FileRecHndl)GetWRefCon(window);
  359.         if ((*frHndl)->fileState.sfType == kDocFileType) {
  360.             enableItem = GetWindowDirty(window);
  361.             if ((*frHndl)->fileState.refNum == kInvalRefNum)
  362.                 enableItem = true;
  363.             if (enableItem)
  364.                 EnableItem(menu, UnmapMItem(mFile, kStdSave));
  365.             EnableItem(menu, UnmapMItem(mFile, kStdSaveAs));
  366.         }
  367.         EnableItem(menu, UnmapMItem(mFile, kDuplicate));
  368.         EnableItem(menu, UnmapMItem(mFile, kStdPageSetup));
  369.         EnableItem(menu, UnmapMItem(mFile, kStdPrint));
  370.     }
  371.  
  372.     return(false);
  373. }
  374.  
  375.  
  376.  
  377. /*****************************************************************************/
  378.  
  379.  
  380.  
  381. #pragma segment Menu
  382. Boolean    DoAdjustEditMenu(WindowPtr window)
  383. {
  384.     MenuHandle        menu;
  385.     Boolean            menuEnabled;
  386.     FileRecHndl        frHndl;
  387.  
  388.     menu = GetMenuHandle(mEdit);
  389.  
  390.     if (IsDAWindow(window)) {
  391.         EnableItem(menu, UnmapMItem(mEdit, kStdUndo));
  392.         EnableItem(menu, UnmapMItem(mEdit, kStdCut));
  393.         EnableItem(menu, UnmapMItem(mEdit, kStdCopy));
  394.         EnableItem(menu, UnmapMItem(mEdit, kStdPaste));
  395.         EnableItem(menu, UnmapMItem(mEdit, kStdClear));
  396.         return(false);
  397.     }
  398.  
  399.     if (IsAppWindow(window)) {
  400.         frHndl = (FileRecHndl)GetWRefCon(window);
  401.         switch ((*frHndl)->fileState.sfType) {
  402. #if VH_VERSION
  403.             case kViewHierFileType:
  404.                 CTEEditMenu(&menuEnabled, mEdit, UnmapMItem(mEdit, kStdUndo),
  405.                                                  UnmapMItem(mEdit, kStdCut));
  406.                 break;
  407. #endif
  408.             default:
  409. #if VH_VERSION
  410.                 EnableItem(menu, UnmapMItem(mEdit, kStdViewHier));
  411. #endif
  412.                 CTEEditMenu(&menuEnabled, mEdit, UnmapMItem(mEdit, kStdUndo),
  413.                                                  UnmapMItem(mEdit, kStdCut));
  414.                 break;
  415.         }
  416.     }
  417.  
  418.     return(false);
  419. }
  420.  
  421.  
  422.  
  423. /*****************************************************************************/
  424.  
  425.  
  426.  
  427. #pragma segment Menu
  428. Boolean    DoAdjustFontsMenu(WindowPtr window)
  429. {
  430.     MenuHandle        menu;
  431.     FileRecHndl        frHndl;
  432.     TEHandle        teHndl;
  433.     short            i, j, mode, fnum;
  434.     TextStyle        styl;
  435.     Str255            str;
  436.  
  437.     menu = GetMenuHandle(mFonts);
  438.  
  439.     for (i = CountMItems(menu); i; --i)
  440.         CheckItem(menu, i, false);
  441.  
  442.     if (!IsAppWindow(window))
  443.         return(false);
  444.  
  445.     frHndl = (FileRecHndl)GetWRefCon(window);
  446.     teHndl = CTEFindActive(nil);
  447.     if ((!teHndl) || (teHndl == (*frHndl)->d.doc.inBox))
  448.         return(false);
  449.  
  450.     for (i = CountMItems(menu); i; --i)
  451.         EnableItem(menu, i);
  452.  
  453.     mode = (doFont | doFace);
  454.     styl.tsFace = 0x7F;        /* Check out all styles. */
  455.     TEContinuousStyle(&mode, &styl, teHndl);
  456.     GetFontName(styl.tsFont, str);
  457.     GetFNum(str, &styl.tsFont);
  458.     if (mode & doFace) {
  459.         if (!(j = styl.tsFace))
  460.             CheckItem(menu, kPlain, true);
  461.         else
  462.             for (i = kBold; i <= kExtend; ++i, j >>= 1)
  463.                 if (j & 0x01)
  464.                     CheckItem(menu, i, true);
  465.     }
  466.     if (mode & doFont) {
  467.         for (i = CountMItems(menu); i >= kFirstFont; --i) {
  468.             GetMenuItemText(menu, i, str);
  469.             GetFNum(str, &fnum);
  470.             if (fnum == styl.tsFont) {
  471.                 CheckItem(menu, i, true);
  472.                 break;
  473.             }
  474.         }
  475.     }
  476.  
  477.     return(false);
  478. }
  479.  
  480.  
  481.  
  482. /*****************************************************************************/
  483.  
  484.  
  485.  
  486. #pragma segment Menu
  487. static short    NewFontSize(short size)
  488. {
  489.     short        item, itype;
  490.     Handle        ihandle;
  491.     Rect        irect;
  492.     Str255        str;
  493.     WindowPtr    oldPort, ww;
  494.     DialogPtr    dialog;
  495.  
  496.     GetPort(&oldPort);
  497.  
  498.     ww     = FrontWindowOfType(kwIsDocument, true);
  499.     dialog = GetCenteredDialog(rNewFontSizeDlg, nil, ww, (WindowPtr)-1L);
  500.     if (dialog) {
  501.         SetPort(dialog);
  502.         if (size) {
  503.             GetDialogItem(dialog, 4, &itype, &ihandle, &irect);
  504.             pcpydec(str, size);
  505.             SetDialogItemText(ihandle, str);
  506.             SelectDialogItemText(dialog, 4, 0, 32767);
  507.         }
  508.         for (size = 0;;) {
  509.             ModalDialog(gKeyEquivFilterUPP, &item);
  510.             if (item == 3) break;
  511.             if (item == 1) {
  512.                 GetDialogItem(dialog, 4, &itype, &ihandle, &irect);
  513.                 GetDialogItemText(ihandle, str);
  514.                 size = p2dec(str, nil);
  515.                 if (size < 6)   size = 6;
  516.                 if (size > 128) size = 128;
  517.                 break;
  518.             }
  519.         }
  520.         DisposeDialog(dialog);
  521.     }
  522.  
  523.     SetPort(oldPort);
  524.     return(size);
  525. }
  526.  
  527.  
  528.  
  529.